/**
 *                            License
 * THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS  
 * CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). 
 * THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.  
 * ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR  
 * COPYRIGHT LAW IS PROHIBITED.
 * 
 * BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND  
 * AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE  
 * MAY BE CONSIDERED TO BE A CONTRACT,
 * THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED 
 * HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
 * 
 */
package lineage.core.handler;

import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedBlockingQueue;

import lineage.core.L1GameClient;
import lineage.core.Opcodes;
import lineage.core.thread.pool.L1ThreadPool;
import lineage.packet.L1AbstractPacketClient;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 封包接收处理程序.
 * 将'读处理器'送来的封包加入队列,轮询处理.
 * 
 * @version 2014年3月11日上午11:56:55
 * @author jrwz
 */
public final class L1PacketAcceptHandler extends L1AbstractHandler implements Runnable {
    private static final Logger LOG = LoggerFactory.getLogger(L1PacketAcceptHandler.class);

    /**
     * 封包接收处理程序.
     * 
     * @param client
     *            - 客户端对象
     */
    public L1PacketAcceptHandler(final L1GameClient client) {
        this.client = client;
        queue = new ConcurrentLinkedQueue<byte[]>();
        L1ThreadPool.getInstance().schedule(this, 0); // 运行线程
    }

    /**
     * 封包接收处理程序.
     * 
     * @param client
     *            - 客户端对象
     * @param capacity
     *            - 此队列的容量
     */
    public L1PacketAcceptHandler(final L1GameClient client, final int capacity) {
        this.client = client;
        queue = new LinkedBlockingQueue<byte[]>(capacity);
        L1ThreadPool.getInstance().schedule(this, 0); // 运行线程
    }

    @Override
    public void run() {
        try {
            while (client.getSocket() != null) {
                for (final Iterator<byte[]> iter = queue.iterator(); iter.hasNext();) {
                    final byte[] data = iter.next(); // 取出元素
                    iter.remove(); // 删除元素
                    execute(data); // 处理
                    Thread.sleep(1);
                }
                Thread.sleep(10);
            }
        } catch (final Exception e) {
            LOG.error(e.getLocalizedMessage(), e);
        } finally {
            close();
        }
    }

    // 直接处理
    @Override
    public void execute(final byte[] data) {
        if (data.length <= 0) {
            return;
        }
        L1AbstractPacketClient packet = null;
        try {
            final int key = data[0] & 0xff;
            packet = Opcodes.LIST.get(key);
            if (packet != null) {
                packet.execute(client, data); // 到相关类处理
            } else {
                LOG.info("客户端发来未知封包：" + "" + key);
            }
        } catch (final Exception e) {
            LOG.error(e.getLocalizedMessage(), e);
        } finally {
            packet = null;
        }
    }

    @Override
    public void executeQueue(final byte[] data) {
        queue.offer(data);
    }

    @Override
    protected void close() {
        queue.clear();
    }
}
